/*
 * Copyright (c) 2024 iSOFT INFRASTRUCTURE SOFTWARE CO., LTD.
 * easyAda is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */

.global atomic_add
.global atomic_sub
.global atomic_load
.global atomic_store
.global atomic_exchange
.global atomic_compare_exchange
.global atomic_get

.section ".text","ax"
/* static inline long atomic_add(atomic_t *p, long val) */
atomic_add:
retry_add:
    ldxr X2, [x0]
    add X2, X1, X2
    stxr w3, X2, [x0]
    cbnz w3, retry_add
    mov X0, X2
    ret

/* static inline long atomic_sub(atomic_t *p, long val) */	
atomic_sub:
retry_sub:
    ldxr x2, [x0]
    sub x2, x2, x1
    stxr w3, x2, [x0]
    cbnz w3, retry_sub
    mov x0, x2
    ret

/* static inline long atomic_load(atomic_t *p) */	
atomic_load:
    ldxr x0, [x0]
    ret

/* static inline long atomic_store(atomic_t *p, long val) */	
atomic_store:
    str x1, [x0]
    mov x0, x1
    ret

/* long atomic_get(atomic_t *p); */
atomic_get:
atomic_get_retry:
    ldxr x1,[x0]
    cmp x1,#0
    ble	atomic_get_end
    sub x1,x1,#1
    stxr w2,x1,[x0]
    cmp w2,#0
    cbnz x2,atomic_get_retry
    mov x0,#1
    ret
atomic_get_end:
    mov x0,#0
    ret

/* static inline long atomic_exchange(atomic_t *p, long val) */	
atomic_exchange:
retry_exchange:
    ldxr x2, [x0]
    stxr w3, x1, [x0]
    cbnz w3, retry_exchange
    mov x0, x2
    ret

/* long atomic_compare_exchange(atomic_t *p, long expected, long newval) */
atomic_compare_exchange:
retry_cas:
    ldxr x3, [x0]
    cmp x3, x1
    beq store
    mov x0,#0
    ret
store:
    stxr w3, x2, [x0]
    cbnz w3, retry_cas
    mov x0, #1
    ret



